﻿using AutoMapper;
using SqlSugar;
using SX.BaseService.Repository.Core;
using SX.BaseService.Repository.Entity;
using SX.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SX.BaseService.Service.Implement.SysPermission
{
    public class SysPermissionService:DbContext,ISysPermissionService
    {
        private IMapper _mapper;
        private readonly IRepository<SysPermissionEntity> _repository;
        public SysPermissionService(IMapper mapper,IRepository<SysPermissionEntity> repository)
        {
            _mapper = mapper;
            _repository = repository;
        }

        public async Task<IApiResult> Add(MenuAddModel model)
        {
            var entity = _mapper.Map<SysPermissionEntity>(model);
            entity.Id = GuidHelper.NewSequentialGuid(SequentialGuidType.SequentialAtEnd);
            entity.CreateTime = DateTime.Now;
            entity.Type = 0;
            var res =await Db.Insertable(entity).ExecuteCommandAsync();
            if (res<=0)
                return ApiResult.NotOk("新增失败");
            return ApiResult.Ok();
        }

        public async Task<IApiResult> Delete(string id)
        {
            var sql = @";with temp as(select * from SysPermission where id=@id
                union all
                select a.* from SysPermission a join temp b on a.ParentId=b.Id where b.Id is not null and b.Id <>''
                )
                select* from temp where [Type]=0";
            var list = await Db.Ado.SqlQueryAsync<SysPermissionEntity>(sql, new { Id=id });
            var ids = list.Select(t => t.Id).Distinct().ToList();
            var count =Db.Deleteable<SysPermissionEntity>().Where(x=>ids.Contains(x.Id)).ExecuteCommand();
            if (count <= 0)
                return ApiResult.NotOk("删除失败");
            return ApiResult.Ok();
        }

        /// <summary>
        /// 递归部门
        /// </summary>
        /// <param name="sourceList">原数据</param>
        /// <param name="list">新集合</param>
        /// <param name="guid">父节点</param>
        /// <returns></returns>
        List<MenuTreeResModel> RecursionOrganize(List<SysPermissionEntity> sourceList, List<MenuTreeResModel> list, string id)
        {
            foreach (var row in sourceList.Where(m => m.ParentId == id && m.Type == 0).OrderBy(m => m.Sort))
            {
                var res = RecursionOrganize(sourceList, new List<MenuTreeResModel>(), row.Id);
                list.Add(new MenuTreeResModel()
                {
                    Id = row.Id,
                    Title = row.Name,
                    Spread = res.Count > 0,
                    Children = res.Count > 0 ? res : null
                });
            }
            return list;
        }
        public async Task<IApiResult> GetTree()
        {
            var list = await Db.Queryable<SysPermissionEntity>().ToListAsync();
            var treeList = new List<MenuTreeResModel>();
            foreach (var item in list.Where(m => m.ParentId.IsNull() && m.Type == 0).OrderBy(m => m.Sort))
            {
                //获得子级
                var children = RecursionOrganize(list.ToList(), new List<MenuTreeResModel>(), item.Id);
                treeList.Add(new MenuTreeResModel()
                {
                    Id = item.Id,
                    Title = item.Name,
                    Spread = children.Count > 0,
                    Children = children.Count == 0 ? null : children
                });
            }
            return ApiResult.Ok(treeList);
        }

        public async Task<IApiResult> Query(MenuQueryModel model)
        {
            RefAsync<int> total = 0;
            var queryable = Db.Queryable<SysPermissionEntity>();
            var list = await queryable
                .Where(x=>x.Type==0)
                .WhereIF(model.Name.NotNull(), x => x.Name.Contains(model.Name))
                .OrderBy(x => x.CreateTime, OrderByType.Desc)
                .ToListAsync();
           
            return ApiResult.Ok(list);
        }

        public async Task<IApiResult> QueryById(string id)
        {
            var data =await Db.Queryable<SysPermissionEntity>().Where(x=>x.Id==id).SingleAsync();
            var parent = await Db.Queryable<SysPermissionEntity>().Where(x => x.Id == data.ParentId).SingleAsync();
            data.ParentName = parent?.Name;
            return ApiResult.Ok(data);
        }

        public async Task<IApiResult> Sort(string p, string i, int o)
        {
            try
            {
                int a = 0, b = 0, c = 0;

                var sql = @";with temp as(select * from SysPermission where id=@id
                union all
                select a.* from SysPermission a join temp b on a.ParentId=b.Id where b.Id is not null and b.Id <>''
                )
                select* from temp where [Type]=0";

                var res = await Db.Ado.SqlQueryAsync<SysPermissionEntity>(sql, new {id=p });
                res.RemoveAll(x => x.Id == p);
                var list = res.OrderBy(m => m.Sort).ToList();

                if (list.Count() > 0)
                {
                    var index = 0;
                    foreach (var item in list)
                    {
                        index++;
                        if (index == 1)
                        {
                            if (item.Id == i) //判断是否是头如果上升则不做处理
                            {
                                if (o == 1) //下降一位
                                {
                                    a = Convert.ToInt32(item.Sort);
                                    b = Convert.ToInt32(list[index].Sort);
                                    c = a;
                                    a = b;
                                    b = c;
                                    item.Sort = a;
                                    await Db.Updateable<SysPermissionEntity>(item).ExecuteCommandAsync();
                                    var nitem = list[index];
                                    nitem.Sort = b;
                                    await Db.Updateable<SysPermissionEntity>(nitem).ExecuteCommandAsync();
                                    break;
                                }
                            }
                        }
                        else if (index == list.Count)
                        {
                            if (item.Id == i) //最后一条如果下降则不做处理
                            {
                                if (o == 0) //上升一位
                                {
                                    a = Convert.ToInt32(item.Sort);
                                    b = Convert.ToInt32(list[index - 2].Sort);
                                    c = a;
                                    a = b;
                                    b = c;
                                    item.Sort = a;
                                    await Db.Updateable<SysPermissionEntity>(item).ExecuteCommandAsync();
                                    var nitem = list[index - 2];
                                    nitem.Sort = b;
                                    await Db.Updateable<SysPermissionEntity>(nitem).ExecuteCommandAsync();
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (item.Id == i) //判断是否是头如果上升则不做处理
                            {
                                if (o == 1) //下降一位
                                {
                                    a = Convert.ToInt32(item.Sort);
                                    b = Convert.ToInt32(list[index].Sort);
                                    c = a;
                                    a = b;
                                    b = c;
                                    item.Sort = a;
                                    await Db.Updateable<SysPermissionEntity>(item).ExecuteCommandAsync();
                                    var nitem = list[index];
                                    nitem.Sort = b;
                                    await Db.Updateable<SysPermissionEntity>(nitem).ExecuteCommandAsync();
                                    break;
                                }
                                else
                                {
                                    a = Convert.ToInt32(item.Sort);
                                    b = Convert.ToInt32(list[index - 2].Sort);
                                    c = a;
                                    a = b;
                                    b = c;
                                    item.Sort = a;
                                    await Db.Updateable<SysPermissionEntity>(item).ExecuteCommandAsync();
                                    var nitem = list[index - 2];
                                    nitem.Sort = b;
                                    await Db.Updateable<SysPermissionEntity>(nitem).ExecuteCommandAsync();
                                    break;
                                }
                            }
                        }
                    }
                }
                return ApiResult.Ok();
            }
            catch (Exception ex)
            {
                return ApiResult.NotOk(ex.Message);
            }
        }

        public async Task<IApiResult> Update(MenuUpdateModel model)
        {
            var entity = _mapper.Map<SysPermissionEntity>(model);

            if (model.ParentIds.Count > 0)
            {
                entity.ParentId = model.ParentIds[model.ParentIds.Count() - 1];
            }
            var res = await _repository.Update(entity);
            if (res<1)
                return ApiResult.NotOk("更新失败");
            return ApiResult.Ok();
        }
    }
}
